<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>Freemarker Support</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a href="core-developers-guide.html">Core Developers Guide</a>&nbsp;&gt;&nbsp;<a href="result-types.html">Result Types</a>&nbsp;&gt;&nbsp;<a href="freemarker-result.html">FreeMarker Result</a>&nbsp;&gt;&nbsp;<a href="freemarker-support.html">Freemarker Support</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Freemarker Support</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14206">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14206">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14206">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14206">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14206">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14206">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><h1 id="FreemarkerSupport-FreemarkerSupport">Freemarker Support</h1><p>Freemarker views can be rendered using the webwork result type <code>freemarker</code>.</p><h3 id="FreemarkerSupport-Configureyouractiontousethefreemarkerresulttype">Configure your action to use the <code>freemarker</code> result type</h3><p>The <code>freemarker</code> result type is defined in <code>struts-default.xml</code>, so normally you just include it, and define your resuts to use <code>type="freemarker"</code>.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">&lt;include file="struts-default.xml"/&gt;
...
&lt;action name="test" class="package.Test"&gt;
  &lt;result name="success" type="freemarker"&gt;/WEB-INF/views/testView.ftl&lt;/result&gt;
&lt;/action&gt;
...
</pre>
</div></div><h3 id="FreemarkerSupport-PropertyResoloution">Property Resoloution</h3><p>Your action properties are automatically resolved - just like in a velocity view.</p><p><strong>for example</strong> <code>${name</code>} will result in <code>stack.findValue("name")</code>, which <em>generaly</em> results in <code>action.getName()</code> being executed.</p><p>A search process is used to resolve the variable, searching the following scopes in order, until a value is found :</p><ul><li>freemarker variables</li><li>value stack</li><li>request attributes</li><li>session attributes</li><li>servlet context attributes</li></ul><h3 id="FreemarkerSupport-ObjectsintheContext">Objects in the Context</h3><p>The following variables exist in the FreeMarker views</p><ul><li><code>req</code> - the current HttpServletRequest</li><li><code>res</code> - the current HttpServletResponse</li><li><code>stack</code> - the current OgnlValueStack</li><li><code>ognl</code> - the OgnlTool instance<ul><li>This class contains useful methods to execute OGNL expressions against arbitary objects, and a method to generate a select list using the &lt;s:select&gt; pattern. (i.e. taking the name of the list property, a listKey and listValue)</li></ul></li><li><code>struts</code> - an instance of StrutsBeanWrapper</li><li><code>action</code> - the current Struts action</li><li><code>exception</code> - <em>optional</em> the Exception instance, if the view is a JSP exception or Servlet exception view</li></ul><h3 id="FreemarkerSupport-FreeMarkerconfigurationwithrecentreleases">FreeMarker configuration with recent releases</h3><p>To configure the freemarker engine that Struts uses, just add a file <code>freemarker.properties</code> to the classpath. The supported properties are those that the Freemarker Configuration object expects - see the <a shape="rect" class="external-link" href="http://freemarker.org/docs/api/freemarker/template/Configuration.html#setSetting(java.lang.String,%20java.lang.String)" rel="nofollow">Freemarker documentation</a> for these.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">default_encoding=ISO-8859-1
template_update_delay=5
locale=no_NO
</pre>
</div></div><h3 id="FreemarkerSupport-UsingstrutsUItags-oranyJSPTagLibrary">Using struts UI tags - or any JSP Tag Library</h3><p>Freemarker has builtin support for using any JSP taglib. You can use JSP taglibs in FreeMarker even if<br clear="none"> a) your servlet container has no support for JSP, or <br clear="none"> b) you didn't specify the taglib in your web.xml - note how in the example below we refer to the taglib by its webapp-absolute URL, so no configuration in web.xml is needed.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;">&lt;#assign s=JspTaglibs["/WEB-INF/struts.tld"] /&gt;

&lt;@s.form method="'post'" name="'inputform'" action="'save.action'" &gt;
    &lt;@s.hidden name="'id'" /&gt;
    &lt;@s.textarea label="'Details'" name="'details'" rows=5 cols=40 /&gt;
    &lt;@s.submit value="'Save'" align="center" /&gt;
&lt;/@s.form&gt;
</pre>
</div></div><p>NOTE : numeric properties for tags MUST be numbers, not strings. as in the rows and cols properties above. if you use cols="40" you will receive an exception. Other than that, the freemarker tag container behaves as you would expect.</p><h3 id="FreemarkerSupport-Dynamicattributessupport">Dynamic attributes support</h3><p>You can specify dynamic attributes with Struts 2 tags like this:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;">&lt;@s.textfield name="test" dynamicAttributes={"placeholder":"input","foo":"bar"}/&gt;
</pre>
</div></div><p>or like this:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;">&lt;@s.textfield name="test" placeholder="input" foo="bar"/&gt;
</pre>
</div></div><p>and for both case, it will be parsed into:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;">&lt;input type="text" name="test" value="" id="test" placeholder="input" foo="bar"/&gt;
</pre>
</div></div><p>You can also use OGNL expressions with dynamic tags like below:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;">&lt;@s.textfield name="test" placeholder="input" foo="checked: %{bar}"/&gt;
</pre>
</div></div><p>When using attributes with hyphens, use the below syntax (you can also leave the single quotes from false if you want)</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">&lt;@s.form dynamicAttributes={'data-ajax':'false'}&gt;
  ...
&lt;/@s.form&gt;</pre>
</div></div></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
